package com.symaster.common.connect.util;

import com.symaster.common.util.IOUtil;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;

/**
 * @author yinmiao
 * @date 2021-09-03 21:02
 */
public class ClientIO {

    public static String getMessage(String message, String tag) {
        int i = message.indexOf(tag);
        if (i != -1) {
            message = message.substring(i + tag.length());
        }
        return message;
    }

    public static String getString(InputStream in) throws IOException {
        return new String(getByteArray(in), StandardCharsets.UTF_8);
    }

    public static byte[] getByteArray(InputStream in) throws IOException {

        ByteArrayOutputStream os = null;
        byte[] result;
        try {
            os = new ByteArrayOutputStream();
            while (true) {
                int read = in.read();
                os.write(read);
                byte[] bytes = new byte[8096];
                int offset;
                while ((offset = in.available()) > 0) {
                    offset = Math.min(offset, bytes.length - 1);
                    int read1 = in.read(bytes, 0, offset);
                    os.write(bytes, 0, offset);
                }
                if (isOver(bytes, os, offset)) break;
            }
            byte[] resultCache = os.toByteArray();
            result = new byte[resultCache.length - getLen()];
            System.arraycopy(resultCache, 0, result, 0, result.length);
        } finally {
            IOUtil.close(os);
        }
        return result;
    }

    public static void writeStr(OutputStream os, String data) throws IOException {
        byte[] bytes = data.getBytes(StandardCharsets.UTF_8);
        writeByte(os, bytes);
    }

    public static void writeByte(OutputStream os, byte[] bytes) throws IOException {
        os.write(bytes);
        os.write(getBytes());
        os.flush();
    }

    public static boolean isOver(byte[] bytes, ByteArrayOutputStream baos, int length) {

        byte[] src1 = bytes;
        byte[] src2 = getBytes();
        int len = length;

        if (src1.length < getLen() || len < getLen()) {
            src1 = baos.toByteArray();
            len = src1.length;
        }

        for (int i = 0; i < src2.length; i++) {
            if (src1[len - src2.length + i] != src2[i]) {
                return false;
            }
        }

        return true;
    }

    public static int getLen() {
        return getBytes().length;
    }

    public static byte[] getBytes() {
        if (byteArray == null) {
            byteArray = OVER.getBytes(StandardCharsets.UTF_8);
        }
        return byteArray;
    }

    private static byte[] byteArray;
    public static final String OVER = "$$$OVER$$$";
}
